/*
 *  scoreBoard - ImageFileManager.cpp
 *  Copyright 2011 W. Reckman. All rights reserved.
 */
#include "RemoteIO.h"
#include "ScoreBoardApp.h"
#include "Utils.h"
#include "ImageFileManager.h"

//--------------------------------------------------------------
ImageFileManager::ImageFileManager( const ScoreBoardApp& appRef_ )
: s( Settings::getInstance() ), appRef( appRef_ )
{}

ImageFileManager::vec_PlayerInfo& ImageFileManager::getQueuedInfoItems() { return queuedInfoItems; }


/******************
 * EVENT HANDLERS *
 ******************/

//--------------------------------------------------------------
void ImageFileManager::onNewPhotoboothFile( EventArgsPhotoboothFile& ev_ ) {
	BoardModel::PlayerInfo qp;
	bool rv;
	const string& filename = ev_.filePath;
	
	ofLog( OF_LOG_NOTICE, "(ImageFileManager.cpp) received new file: %s", filename.c_str() );
	
	rv = parseFilename( filename, qp );
	if ( rv ) {
		const BoardModel& board = appRef.getBoard();
		int foundQp = -1;
		for ( int i = 0; i < incompleteInfoItems.size(); ++i ) {
			if ( board.playerInfosEqual( qp, incompleteInfoItems[i] ) ) {
				foundQp = i;
				break;
			}
		}
		
		if ( foundQp >= 0 ) {
			if ( ( qp.topImagePath && ! incompleteInfoItems[foundQp].topImagePath ) || ( qp.bottomImagePath && ! incompleteInfoItems[foundQp].bottomImagePath ) ) {
				if ( qp.topImagePath ) incompleteInfoItems[foundQp].topImagePath = qp.topImagePath;
				else incompleteInfoItems[foundQp].bottomImagePath = qp.bottomImagePath;
				ofLog( OF_LOG_NOTICE, "(ImageFileManager.cpp) completing player info (top img = '%s'", incompleteInfoItems[foundQp].topImagePath->c_str() );
				
				//copy item to queued items and remove from incomplete items
				queuedInfoItems.push_back( incompleteInfoItems[foundQp] );
				incompleteInfoItems.erase( incompleteInfoItems.begin() + foundQp );
			} else {
				ofLog( OF_LOG_WARNING, "(ImageFileManager.cpp) found duplicate/incorrect/missing file _NOT_ matching with counterpart...add more debug logging for details (sorry)" );
			}
		} else {
			incompleteInfoItems.push_back( qp );
			ofLog( OF_LOG_NOTICE, "(ImageFileManager.cpp) adding first half of player info (waiting for counterpart)" );
		}
	} else {
		ofLog( OF_LOG_WARNING, "(ImageFileManager.cpp) ignoring received player image with improperly formatted name ('%s')", filename.c_str() );
	}
}


/*********************
 * PRIVATE FUNCTIONS *
 *********************/

//--------------------------------------------------------------
//NOTE: filename format is MM-DD-hh-mm-ss-ccc-iii-p_{Top,Bottom}.png
//NOTE: slashes are not allowed in the filename
bool ImageFileManager::parseFilename( const string& name, BoardModel::PlayerInfo& qp ) {
	static const int fieldCount = 8;
	static const char splitChar = '-';
	
	string stripped = name.substr( 0, name.rfind( '.' ) );
	stripped = stripped.substr( stripped.rfind( '/' ) + 1 );
	
	int topIdx = stripped.find( "_Top" );
	int bottomIdx = stripped.find( "_Bottom" );
	
	if ( topIdx != string::npos ) {
		stripped = stripped.substr( 0, topIdx );
	} else if ( bottomIdx != string::npos ) {
		stripped = stripped.substr( 0, bottomIdx );
	} else {
		return false; //EXIT point
	}
	
	std::vector<string>* tokens = tokenize( stripped, splitChar );
	
	if ( tokens->size() != fieldCount ) return false; //EXIT point
	
	for ( int i = 0; i < tokens->size(); ++i ) {
		int v = ofToInt( (*tokens)[i] );
		switch ( i ) {
			case 0: qp.month = v; break;
			case 1: qp.day = v; break;
			case 2: qp.hours = v; break;
			case 3: qp.minutes = v; break;
			case 4: qp.seconds = v; break;
			case 5: qp.cultureTgt = v; break;
			case 6: qp.industryTgt = v; break;
			case 7: qp.id = v - 1; break;
		}
	}
	
	if ( qp.topImagePath != 0 ) delete qp.topImagePath;
	if ( qp.bottomImagePath != 0 ) delete qp.bottomImagePath;
	qp.topImagePath = qp.bottomImagePath = 0;
	
	qp.goodPickups = qp.badPickups = 0;
	qp.color = appRef.getBoard().getPlayerColor( qp.id );
	
	if ( topIdx != string::npos ) qp.topImagePath = new string( name );
	else qp.bottomImagePath = new string( name );
	
	return true;
}
